﻿using System.Linq;
using Behaviorize.CodeGenerator.CodeModel;
using EnvDTE;
using EnvDTE80;

namespace Behaviorize.CodeGenerator.CodeGenerating
{
	internal static class ScenariosCodeGenerator
	{
		internal static void CreateOrUpdateCode(Feature feature, CodeClass2 scenariosClass)
		{
			foreach (var scenario in feature.Scenarios)
			{
				CreateorUpdateScenario(scenario, scenariosClass);
			}
		}

		private static void CreateorUpdateScenario(Scenario scenario, CodeClass2 scenariosClass)
		{
			CodeFunction scenarioMethod = GetScenarioMethod(scenario, scenariosClass);

			EditPoint startPoint = scenarioMethod.GetStartPoint(vsCMPart.vsCMPartBody).CreateEditPoint();
			EditPoint endPoint = scenarioMethod.GetEndPoint(vsCMPart.vsCMPartBody).CreateEditPoint();

			startPoint.Delete(endPoint);

			startPoint.Insert(scenario.RenderCode());

			startPoint = scenarioMethod.GetStartPoint(vsCMPart.vsCMPartBody).CreateEditPoint();
			startPoint.SmartFormat(scenarioMethod.GetEndPoint(vsCMPart.vsCMPartBody));
		}

		private static CodeFunction GetScenarioMethod(Scenario scenario, CodeClass2 scenariosClass)
		{
			CodeFunction method = scenariosClass.Children.OfType<CodeFunction>().SingleOrDefault(f => f.Name == scenario.Name.AsPascal());

			if (method == null)
			{
				method = scenariosClass.AddFunction(scenario.Name.AsPascal(),
				                                    vsCMFunction.vsCMFunctionFunction,
				                                    vsCMTypeRef.vsCMTypeRefVoid,
				                                    Access: vsCMAccess.vsCMAccessPublic,
													Position: 1);
				method.AddAttribute("TestMethod", null);
			}

			return method;
		}
	}
}